home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / faq / comp / unix_faq / shell / rc < prev    next >
Internet Message Format  |  1994-04-08  |  45KB

  1. Path: bloom-beacon.mit.edu!hookup!swrinde!sdd.hp.com!saimiri.primate.wisc.edu!news.doit.wisc.edu!oldp.astro.wisc.edu!alan
  2. From: alan@oldp.astro.wisc.edu (Alan Watson)
  3. Newsgroups: comp.unix.shell,comp.answers,news.answers
  4. Subject: rc shell Frequently Asked Questions
  5. Followup-To: poster
  6. Date: 8 Apr 1994 20:13:11 GMT
  7. Organization: Department of Astronomy, University of Wisconsin -- Madison
  8. Lines: 1098
  9. Approved: news-answers-request@MIT.Edu
  10. Expires: 04 May 1994
  11. Message-ID: <2o4dsn$j3j@news.doit.wisc.edu>
  12. NNTP-Posting-Host: oldp.astro.wisc.edu
  13. Summary: Answers to Frequently Asked Questions about rc -- a clean,
  14.          portable, and freely-available shell for UNIX systems.
  15. Originator: alan@oldp.astro.wisc.edu
  16. Xref: bloom-beacon.mit.edu comp.unix.shell:9508 comp.answers:4824 news.answers:17834
  17.  
  18. Archive-name: unix-faq/shell/rc
  19. Comp-unix-shell-archive-name: rc-FAQ
  20. Version: 2.16
  21. Last-modified: 08 Apr 1994
  22.  
  23. This document attempts to answer some Frequently Asked Questions about
  24. rc, a clean, portable, and freely-available shell for UNIX systems (see
  25. 1.1 for a very brief overview of rc).  It in no way replaces either the
  26. formal documentation for rc (see 1.2) or the mailing list archives (see
  27. 2.2).
  28.  
  29. This document draws heavily on the collective wisdom of the rc mailing
  30. list; the quality of the correspondence is such that often all that was
  31. required was a summary of one or two messages.  The rc mailing list
  32. archive is recommend reading for newcomers to rc (see 2.2).
  33. Contributors are acknowledged at the end of this document.
  34.  
  35. Corrections, comments, and suggestions concerning this document are
  36. welcome (see 3.2).
  37.  
  38. NOTE: Neither the editor nor any of the contributors to this document
  39. are responsible for any consequences resulting from the advice in this
  40. document.
  41.  
  42. Table of Contents
  43.  
  44. 1.      Implementations of rc
  45. 1.1     What is rc?
  46. 1.2     Where is rc documented?
  47. 1.3     How do I obtain rc?
  48. 1.4     Are there any patches to rc?
  49. 1.5     Can I compile rc on a ... machine with ... operating system and
  50.         ... compiler?
  51. 1.6     Should rc be dynamically or statically linked?
  52. 1.7     To whom do I report bugs?
  53. 1.8     Does anyone have an implementation of /dev/fd for my UNIX?
  54.  
  55. 2.      The rc mailing list
  56. 2.1     How do I subscribe to the rc mailing list?
  57. 2.2     How do I obtain the rc mailing list archive?
  58.  
  59. 3.      The rc FAQ list
  60. 3.1     How do I obtain the current version of the rc FAQ list?
  61. 3.2     To whom do I make suggestions about the rc FAQ list?
  62.  
  63. 4.      Does rc have ... ?
  64. 4.1     Does rc have job control?
  65. 4.2     Does rc have command-line editing?
  66. 4.3     Does rc have a history mechanism?
  67. 4.4     Does rc have file name completion?
  68. 4.5     Does rc have home directory expansion?
  69. 4.6     Does rc check for new mail?
  70. 4.7     Does rc have hierarchical lists?
  71. 4.8     Does rc have cartesian products?
  72. 4.9     Does rc cache the location of executables in the path?
  73. 4.10    Does rc have C-style \ escapes?
  74. 4.11    Does rc have ... built in?
  75. 4.12    Does rc have echo built in?
  76. 4.13    Does rc have test built in?
  77. 4.14    Does rc have true, false, and `:' built in?
  78.  
  79. 5.      Using rc as a login shell
  80. 5.1     How do I make rc my login shell?
  81. 5.2     How do I use rc in a heterogeneous cluster?
  82. 5.3     What problems occur with rc on Apollos?
  83. 5.4     What problems occur with rc on SYSV-derived systems?
  84. 5.5     What problems occur with rc on NeXTs?
  85. 5.6     How do I keep down the size of my .rcrc file?
  86. 5.7     How do I speed up the execution of my .rcrc file?
  87.  
  88. 6.      Interactions between rc and the rest of UNIX
  89. 6.1     How do I get each new interactive rc to do ...?
  90. 6.2     How do I get rc to do ... in each new xterm?
  91. 6.3     How do I get rc to read .rcrc when I use rsh?
  92. 6.4     How do I get at or batch to run an rc script?
  93.  
  94. 7.      Programming in rc
  95. 7.1     What makes rc such a good scripting language?
  96. 7.2     What are the trade-offs between functions and scripts?
  97. 7.3     What can I do if I have deficient sed, awk, test, ... ?
  98. 7.4     Where do I obtain the GNU tools and other software?
  99. 7.5     How do I perform arithmetic in rc?
  100. 7.6     How do I find the first occurrence of an element in a list?
  101. 7.7     How do I use ranges in array subscripts in rc?
  102. 7.8     How do I perform the equivalent of read in rc?
  103.  
  104. 1.      Implementations of rc
  105.  
  106. 1.1     What is rc?
  107.  
  108.         rc is a shell designed by Tom Duff of Bell Labs to replace the
  109.         venerable Bourne sh in Plan 9.  (Plan 9 is an experimental
  110.         operating and networking system developed at Bell Labs.)  In
  111.         addition to Plan 9, Duff's rc runs on SunOS and v10 UNIX.  The
  112.         design of rc is extremely clean, in that precisely those
  113.         features of Bourne's sh that have caused problems over the years
  114.         (the slightly awkward flow control syntax, the Byzantine quoting
  115.         rules, the failure to export all variables into the environment)
  116.         were reworked, and the temptation to add superfluous features
  117.         was strongly resisted.
  118.  
  119.         Byron Rakitzis has written a version of rc that is portable
  120.         between many version on UNIX and is largely compatible with
  121.         Duff's design.  Rakitzis' implementation has been successfully
  122.         used on UNIX platforms ranging from PCs running Linux to Cray
  123.         Y-MPs running Unicos.
  124.  
  125.         Most of this document deals with issues that have arisen from
  126.         use of Rakitzis' rc, and most of the example code will follow
  127.         his minor modifications to rc.  Henceforth, a plain `rc' refers
  128.         to Rakitzis' rather than Duff's rc.
  129.  
  130. 1.2     Where is rc documented?
  131.  
  132.         rc is documented in its man page, distributed with the source
  133.         (see 1.3).
  134.  
  135.         The Plan 9 manual pages, including those on Duff's rc, are
  136.         available as research.att.com:/dist/plan9man/manual.ps.Z by
  137.         anonymous FTP.  The full manual is almost 600 pages long, but
  138.         the manual pages for Duff's rc are physical pages 142 to 147
  139.         (logical pages 116 to 121).
  140.  
  141.         An early version of Duff's rc is described in the paper `rc -- a
  142.         Shell for Plan 9 and UNIX Systems', written for a UKUUG meeting.
  143.         Duff has kindly allowed the paper to be distributed by anonymous
  144.         FTP as viz.tamu.edu:/pub/rc/plan9.ps.  It provides an excellent
  145.         introduction and tutorial for Duff's rc, and describes the
  146.         motivations for the differences between Duff's rc and Bourne's
  147.         sh.
  148.  
  149.         When reading Duff's paper and the Plan 9 manual pages, bear in
  150.         mind that Rakitzis' implementation of rc differs in detail from
  151.         Duff's (these differences are documented in the rc man page).
  152.  
  153.         Another valuable source of information on rc is the rc mailing
  154.         list archive (see 2.2).
  155.  
  156. 1.3     How do I obtain rc?
  157.  
  158.         The sources are available by anonymous FTP in the directory
  159.         viz.tamu.edu:/pub/rc.  Be sure to get the most recent version.
  160.         At the time this document was last updated, the most recent
  161.         version of rc was v1.4 announced on 21 May 1992, available as
  162.         viz.tamu.edu:/pub/rc/rc-1.4.tar.Z.  (A beta release of v1.5 is
  163.         on the horizon.)
  164.  
  165.         rc is distributed on very liberal terms, although it has not
  166.         been placed in the public domain (see the file COPYRIGHT
  167.         distributed with the sources).
  168.  
  169.         Duff's rc can be obtained by acquiring either a Plan 9 or a v10
  170.         UNIX system from Bell Labs.  Plan 9 can be licensed by academic
  171.         institutions, which should contact:
  172.  
  173.             Neera Kuckreja
  174.             RM 2C557
  175.             ATT Bell Laboratories
  176.             Murray Hill
  177.             NJ 07974
  178.             USA
  179.             +1 908 582-3855
  180.             neera@research.att.com
  181.  
  182. 1.4     Are there any patches to rc?
  183.  
  184.         Although the current version of rc is remarkably mature, a small
  185.         number of bugs have been found since its release and patches
  186.         have been posted to the rc mailing list (see 2.2).  Other
  187.         patches posted to the mailing list include work-arounds for
  188.         broken compilers or libraries and assorted features.
  189.  
  190.         An up-to-date set of patches extracted from the mailing list
  191.         archive, together with a script to apply those patches, is
  192.         available as oldp.astro.wisc.edu:/pub/rc/patches.tar.Z by
  193.         anonymous FTP.
  194.  
  195. 1.5     Can I compile rc on a ... machine with ... operating system and
  196.         ... compiler?
  197.  
  198.         rc is written in portable ANSI C, but it can be compiled by many
  199.         older C compilers after passing the sources through unproto (get
  200.         ftp.win.tue.nl:/pub/unix/unproto4.shar.Z by anonymous FTP).
  201.  
  202.         If you use gcc, use v1.39 or later.
  203.  
  204.         rc has been successfully compiled on systems with the following
  205.         combinations of architectures, operating systems, and compilers,
  206.         although this list is probably not exhaustive:
  207.  
  208.             DEC VAX        Ultrix v3.x            gcc v1
  209.             DEC MIPS       Ultrix v4.[23]         gcc v2
  210.             DEC MIPS       Ultrix v4.[23]         cc          [a]
  211.             DEC AXP        OSF/1 v1.2             cc          [a][b]
  212.             DEC AXP        OSF/1 v1.2             cc -std1    [b]
  213.  
  214.             Sun SPARC      Solaris v2             gcc v2      [b][c]
  215.             Sun SPARC                             acc         [b][c]
  216.             Sun SPARC      SunOS v4.1.[123]       cc          [a][b][c]
  217.             Sun SPARC      SunOS v4.1.[123]       gcc v2      [b][c]
  218.             Sun SPARC      BSD                                [b][c]
  219.             Sun 68K        SunOS v4.1.1           gcc v2      [b][c]
  220.             Sun 68K        SunOS v3.5             gcc v1      [b][c]
  221.  
  222.             SGI Iris       Irix v[45].x           gcc v2
  223.  
  224.             IBM RS/6000    AIX v3.1.5             cc
  225.             IBM RS/6000    AIX v3.2.[013]         cc
  226.  
  227.             HP PA-RISC     HP-UX v8.0             gcc v2      [d][e]
  228.             HP PA-RISC     HP-UX v9.0             gcc v2      [d]
  229.             HP PA-RISC     OSF/1 v1.0.2           cc
  230.  
  231.             i386/i486      SCO-ODT SVR3           gcc v2      [d][e]
  232.             i386/i486      SCO-ODT SVR3           cc          [d][e]
  233.             i386           Minix v1.5                         [d]
  234.             i386/i486      NetBSD                 gcc v[12]
  235.             i386/i486      Linux                  gcc v2      [d]
  236.             i386/i486      386BSD r0.0            gcc         [j]
  237.             i386/i486      SCO Xenix SVR2.3x                  [f]
  238.  
  239.             NeXT           NeXT OS v2.x           gcc v[12]   [g]
  240.             NeXT           NeXT OS v3.0           gcc v2      [g]
  241.  
  242.             Apollo 68K     DomainOS v10.4 (BSD)   cc          [h]
  243.             Apollo 10000   DomainOS v10.4 (BSD)   cc          [h]
  244.  
  245.             Sony MIPS      NEWS/OS                cc          [a]
  246.             Sony 68K       NEWS/OS v4.0.1         cc          [a]
  247.  
  248.             Convex C1      ConvexOS v10.1         cc
  249.  
  250.             Pyramid 9810   OSx 5.1a (BSD)         cc -Xa      [i]
  251.  
  252.             Cray Y-MP      Unicos 6.1.7           scc         [e][j]
  253.  
  254.             Sequent        Dynix v3.2.0 (BSD)     gcc v2
  255.  
  256.             Apple 68K      A/UX v3.0              cc
  257.  
  258.             Encore MIPS    Umax v4.3              gcc v2
  259.  
  260.             Acorn ARM      iX v1.21a              cc
  261.  
  262.             Motorola 88K   System V R32V3         gcc v2
  263.             Motorola 88K   System V R32V3         cc          [a][k]
  264.  
  265.         Notes:
  266.  
  267.             [a] Sources pre-processed with unproto.
  268.             [b] See 1.6.
  269.             [c] Sun's yacc has a memory leak -- use another
  270.                 implementation such as GNU bison (see 7.4).
  271.             [d] Requires intervention by hand to get mksignal to work,
  272.                 because of of the non-standard signal.h file.
  273.             [e] See 4.13.
  274.             [f] See 5.4.
  275.             [g] See 5.5.
  276.             [h] See 5.3
  277.             [i] This compiler has no stdarg.h, but vararg.h sufficed.
  278.             [j] Minor modifications required to prototypes.
  279.             [k] Greenhills cc, used without any optimization.
  280.  
  281. 1.6     Should rc be dynamically or statically linked?
  282.  
  283.         As far as one can generalize, statically linked executables fork
  284.         faster than dynamically linked executables.  This suggests that
  285.         shells, which fork a great deal, should probably be statically
  286.         linked (i.e., you should not link them with shared libraries).
  287.         rc makes so little use of libc functions that static linking
  288.         results in only a small increase in the size of the executable
  289.         on disc.
  290.  
  291.         Versions of UNIX which support shared libraries include SVR4,
  292.         SunOS, Solaris, OSF/1, and Irix.
  293.  
  294. 1.7     To whom do I report bugs?
  295.  
  296.         Byron Rakitzis (byron@netapp.com) or the rc mailing list
  297.         (rc@hawkwind.utcs.toronto.edu).  Please check the documentation
  298.         before reporting bugs, and check the mailing list archive in
  299.         case the bug is already known.
  300.  
  301. 1.8     Does anyone have an implementation of /dev/fd for my UNIX?
  302.  
  303.         /dev/fd pseudo-devices allow a more reliable implementation of
  304.         non-linear pipelines (i.e., <{...}  and >{...}) than named
  305.         pipes, but they are not present in all versions of UNIX.
  306.  
  307.         An implementation of Ultrix v4.2 and later was posted to the
  308.         mailing list in March 1993 (see 2.2).
  309.  
  310.         An implementation for SunOS v4.1.1 is also available (although
  311.         it may well work with v4.1.2 and v4.1.3) by anonymous FTP as
  312.         ftp.cs.arizona.edu:/devfd.shar.
  313.  
  314.         An implementation for SunOS v4.1.2 is available by anonymous FTP
  315.         as emx.cc.utexas.edu:/pub/mnt/source/sun/devfd.shar.  (This is
  316.         packaged as a loadable module, so you do not have to rebuild
  317.         your kernel.)
  318.  
  319.         An implementation for NeXT OS 2.1 is available by anonymous FTP
  320.         as ftp.sys.toronto.edu:/pub/rc/devfd-next.shar.gz.
  321.  
  322.         You will, of course, need to rebuild your kernel to install
  323.         these pseudo-devices.
  324.  
  325. 2.      The rc mailing list
  326.  
  327. 2.1     How do I subscribe to the rc mailing list?
  328.  
  329.         Send mail to
  330.  
  331.             rc-request@hawkwind.utcs.toronto.edu.
  332.  
  333.         Chris Siebenmann maintains the mailing list, and can be reached
  334.         at the above address in the event of problems with the mailing
  335.         list or to unsubscribe.
  336.  
  337.         The rc mailing list represents hundreds of user-years of
  338.         experience with rc.  Clearly, it is a courtesy to the list and
  339.         to your own advantage to check the mailing list archive before
  340.         posting to the list, to benefit from the experience and mistakes
  341.         of those before you, and to prevent topics being continually
  342.         rehashed.
  343.  
  344. 2.2     How do I obtain the rc mailing list archive?
  345.  
  346.         The archive can be obtained by anonymous FTP.  At the moment, it
  347.         is split chronologically between the original and current
  348.         maintainers of the mailing list.
  349.  
  350.         Period              File
  351.         Jun 91 to Dec 91    viz.tamu.edu:/pub/rc/rc-list.1991.Z
  352.         Jan 92 to May 92    viz.tamu.edu:/pub/rc/rc-list
  353.         May 92 to present   ftp.sys.toronto.edu:/pub/rc/rc-list
  354.  
  355. 3.      The rc FAQ list
  356.  
  357. 3.1     How do I obtain the current version of the rc FAQ list?
  358.  
  359.         The current version of the rc FAQ list is available by anonymous
  360.         FTP as oldp.astro.wisc.edu:/pub/rc/rc-FAQ.  This FAQ is also
  361.         archived automatically and is available by anonymous FTP as
  362.         rtfm.mit.edu:/pub/usenet/comp.unix.shell/rc-FAQ.
  363.  
  364. 3.2     To whom do I make suggestions about the rc FAQ list?
  365.  
  366.         To its editor, Alan Watson (alan@oldp.astro.wisc.edu), or the rc
  367.         mailing list if you think your suggestion warrants a wider
  368.         audience.
  369.  
  370. 4.      Does rc have ... ?
  371.  
  372. 4.1     Does rc have job control?
  373.  
  374.         No.  This has been discussed at length in the rc mailing list.
  375.  
  376.         Now that personal workstations with window systems are common
  377.         place, the case for job control is less compelling.  However, if
  378.         you have to use rc on a traditional terminal, you may wish to
  379.         obtain the screens program from a GNU archive (see 7.4), the sm
  380.         program that was posted to alt.sources in mid-1992 (see 7.4), or
  381.         investigate shell escape mechanisms in vi and shell mode in
  382.         emacs.
  383.  
  384. 4.2     Does rc have command-line editing?
  385.  
  386.         If you wish.  Hooks are provided for the readline or editline
  387.         libraries which provide command-line editing.  The default is no
  388.         command-line editing.
  389.  
  390.         The readline library can be obtained from a GNU archive (see
  391.         7.4).
  392.  
  393.         The editline library is similar to the readline library, but is
  394.         a fraction of the size and offers fewer features.  The sources
  395.         are available as ftp.sys.toronto.edu:/pub/rc/editline.shar by
  396.         anonymous FTP).
  397.  
  398.         Alternatively, you can use fep, ile, atty, or Rk to implement
  399.         editing on a per-terminal basis.  These have been discussed in
  400.         on the mailing list at one time or another, and modifications to
  401.         ile have been posted there.
  402.  
  403. 4.3     Does rc have a history mechanism?
  404.  
  405.         Yes.  While, rc does not have a built-in csh-like history
  406.         mechanism, rather it is able to write interactive commands to a
  407.         file (see the history special variable in the man page),
  408.         allowing a history mechanism similar to the v8 `=' command to be
  409.         implemented as an external program (one such implementation is
  410.         supplied with the source of rc).
  411.  
  412.         In Plan 9, `:' was the history program (the name was probably
  413.         changed from the `=' used in v8 because `=' is a special
  414.         character in rc, and needs quoting if it refers to a command).
  415.         However, this form of history was apparently used so little that
  416.         the ability to write commands to a file was removed from Duff's
  417.         rc.  The history program distributed with the rc source is
  418.         invoked with `-'.
  419.  
  420.         Both editline and readline have command recall.
  421.  
  422. 4.4     Does rc have file name completion?
  423.  
  424.         If you wish.  Plain rc does not have file name completion (as it
  425.         obtains its command input with read), but the readline library
  426.         does.
  427.  
  428. 4.5     Does rc have home directory expansion?
  429.  
  430.         No.  This has been hotly debated on the rc mailing list, and a
  431.         patch to implement this was posted to the rc mailing list in
  432.         November 1992 (see 2.2 and 1.4).
  433.  
  434. 4.6     Does rc check for new mail?
  435.  
  436.         No.  However, you can make it do so with the following prompt
  437.         function:
  438.  
  439.             fn prompt { mail -e && echo You have mail. }
  440.  
  441.         Alternatively, consider using biff or xbiff.
  442.  
  443. 4.7     Does rc have hierarchical lists?
  444.  
  445.         No.  Each element of an rc list must be a string, and cannot be
  446.         another list.  Whenever a list appears inside another list, it
  447.         is expanded so that the outer list contains its elements.
  448.         Similarly, whenever two lists are adjacent, they are
  449.         concatenated to form a single list (with one exception).
  450.  
  451.         In rc terms, the arguments to a command form a list, even though
  452.         they may not have explicit `(' and `)' delimiters around them.
  453.         Hierarchical lists do not correspond well to the `char **argv'
  454.         model for arguments to UNIX commands, although simple lists do.
  455.  
  456.         The single exception to these rules are the arguments to the `~'
  457.         built-in command, which rc interprets as two lists -- a subject
  458.         list and a pattern list.  Normal expansion and concatenation is
  459.         performed on the two lists separately.  A consequence of this is
  460.         that the following command:
  461.  
  462.                 if ( ~ $1 () '' ) ...
  463.  
  464.         does not check if $1 is either the null list or the null string,
  465.         as normal list concatenation occurs on the pattern list leading
  466.         to a pattern list with one element -- the null string.
  467.  
  468. 4.8     Does rc have cartesian products?
  469.  
  470.         No.  If you really need them, they can be obtained in the
  471.         following manner:
  472.  
  473.             ; x = (a b c)
  474.             ; y = (1 2 3)
  475.             ; product = ()
  476.             ; for ( elem in $x ) product = ( $product $elem^$y )
  477.             ; echo $product
  478.             a1 a2 a3 b1 b2 b3 c1 c2 c3
  479.  
  480.         rc's concatenation operator works in a distributive manner if
  481.         one of the lists has only a single element and in a pairwise
  482.         manner if both lists have the same number of elements:
  483.  
  484.             ; echo a^( x y z )
  485.             ax ay az
  486.             ; echo ( a b c )^( x y z )
  487.             ax by cz
  488.  
  489. 4.9     Does rc cache the location of executables in the path?
  490.  
  491.         No.  This has been discussed on the mailing list.  As far as one
  492.         can generalize, searching the path is not a performance
  493.         bottleneck on most modern UNIX systems.
  494.  
  495. 4.10    Does rc have C-style \ escapes?
  496.  
  497.         No.  One of the most attractive features of rc is its single
  498.         quoting rule.
  499.  
  500.         If you need to embed control characters in your strings,
  501.         investigate tr and printf (see 7.3 if your system lacks the
  502.         latter).
  503.  
  504. 4.11    Does rc have ... built in?
  505.  
  506.         It is not by accident that rc has fewer built-in commands than
  507.         most shells other than the original Bourne shell.  The
  508.         underlying philosophy, eloquently summarized by Boyd Roberts, is
  509.         that a shell is there to run other programs, not to have other
  510.         programs built into it.  By having a well-defined role, rc has
  511.         remained small and simple, properties that lead to better
  512.         performance, fewer bugs, and a more thorough understanding of
  513.         the shell by its users.
  514.  
  515.         Most of the rc built-in commands perform functions that are
  516.         essential for a shell and cannot be performed by external
  517.         programs (e.g., cd, eval, limit, umask, wait).
  518.  
  519.         rc does include hooks for users to add new built-in commands,
  520.         and these have been used to add test, access, kill, read, and
  521.         even sync and haltsys commands (see the mailing list and the
  522.         examples file for more details).  Such additions are unsupported
  523.         and potentially unportable.
  524.  
  525. 4.12    Does rc have echo built in?
  526.  
  527.         If you wish.  While most of rc's built-in commands could not
  528.         easily be replaced by external commands, echo is the one
  529.         exception.  The justification is that echo is used so much that
  530.         providing it as a built-in command results in a significant gain
  531.         in performance, although this opinion is by no means universally
  532.         held.  By default, echo is built in.
  533.  
  534.         It has also been noted that rc's echo is more portable that
  535.         /bin/echo, as the v7 and SYSV implementations of echo differ in
  536.         the method that must be used to suppress the final newline.
  537.         (However, rc's echo differs from both, as it uses `--' to
  538.         indicate that all other arguments are to be echoed literally.)
  539.  
  540.         People who dislike the notion of a built-in echo command have
  541.         the option of excluding it from the compilation.  Alternatively,
  542.         the built-in echo can be subverted with the following function,
  543.         although this will not defeat an explicit call to `builtin
  544.         echo'.
  545.  
  546.             fn echo { /bin/echo $* }
  547.  
  548.         See also 7.3.
  549.  
  550. 4.13    Does rc have test built in?
  551.  
  552.         No.  You can use the built-in `~' command to match strings, and
  553.         fall back on /bin/expr or /bin/test for numeric comparisons and
  554.         /bin/test for querying the file system.
  555.  
  556.         If you are using rc on a system that lacks a stand-alone
  557.         /bin/test and /bin/[ and has test built into sh, the following
  558.         serves as an interim replacement:
  559.  
  560.             #! /bin/sh
  561.             `basename $0` ${1+"$@"}
  562.             # end-of-file
  563.  
  564.         This applies to Unicos and HP-UX v8.  Note that trip.rc, the
  565.         script provided with the rc sources to check basic functionality
  566.         after compilation, will fail unless a suitable test command
  567.         exists in the path.
  568.  
  569.         SCO UNIX implements /bin/test in precisely this way.  You can
  570.         almost certainly get better performance by using the GNU
  571.         implementation of /bin/test (see 7.4), although this is
  572.         obviously more important on an i386 machine than on a Cray.
  573.  
  574.         It is possible to get at the file system obliquely through the
  575.         globbing mechanism and the builtin cd command, and in some
  576.         circumstances these can be of use (see, for example, 5.7).  Such
  577.         speed hacks need to be carefully justified.
  578.  
  579.         See also 7.3.
  580.  
  581. 4.14    Does rc have true, false, and `:' built in?
  582.  
  583.         No.  The following functions are just as fast:
  584.  
  585.             fn true  { return 0 }
  586.             fn false { return 1 }
  587.             fn : { return 0 }
  588.  
  589.         Note that an indefinite loop in rc does not require the use of
  590.         an explicit `true' command:
  591.  
  592.             while () {
  593.                 ...
  594.             }
  595.  
  596. 5.      Using rc as a login shell
  597.  
  598. 5.1     How do I make rc my login shell?
  599.  
  600.         On most systems, you or the system administrator will have to
  601.         add a line to /etc/shells containing the full path to rc.  This
  602.         will need to be done on each machine on which you wish to use
  603.         rc.
  604.  
  605.         Next, use the chsh command to specify your new preference.  If
  606.         your machine is running Yellow Pages (YP), you will have to do
  607.         this on the YP server, otherwise you will have to do this on
  608.         each machine individually.  (To determine if your machine is
  609.         using YP, type `ypwhich -m passwd' that will either print the
  610.         name of your YP server or give an error if your machine is not
  611.         running YP.)  Often, you will also need to change your password
  612.         (using the yppasswd command) on the YP server to propagate the
  613.         new /etc/passwd entry contain your selected shell; changing your
  614.         password to itself will normally suffice.
  615.  
  616.         An alternative method is to invoke rc from your .profile file or
  617.         its equivalent, but this has so many drawbacks that I cannot
  618.         recommend it.
  619.  
  620. 5.2     How do I use rc in a heterogeneous cluster?
  621.  
  622.         There are two issues: finding the correct executable when you
  623.         login, and getting the correct path in scripts run using the #!
  624.         kernel hack.
  625.  
  626.         If you have root privileges on every machine on the cluster, by
  627.         far the simplest solution is the place a copy of rc in /bin and
  628.         add /bin/rc to /etc/shells on each machine.  Use `#! /bin/rc' in
  629.         shell scripts.
  630.  
  631.         Otherwise, use a sh wrapper around rc.  Create a shell script
  632.         called, say, rc-login, and make this your login shell.  The
  633.         purpose of this script is to set SHELL and PATH to point
  634.         appropriately according to the machine, and then to exec rc.
  635.  
  636.         The following script is suitable for adaptation:
  637.  
  638.             #! /bin/sh
  639.  
  640.             # determine OS
  641.             TMP=/tmp/$$
  642.             ( exec >$TMP ; echo OS=`uname -m` )
  643.             . $TMP
  644.             rm -f $TMP
  645.  
  646.             # determine location of rc executable
  647.             case $OS in
  648.             RISC)
  649.                PATH=$HOME/bin/mips:$PATH
  650.                SHELL=$HOME/bin/mips/rc
  651.                ;;
  652.             sun4c)
  653.                PATH=$HOME/bin/sparc:$PATH
  654.                SHELL=$HOME/bin/sparc/rc
  655.                ;;
  656.             alpha)
  657.                PATH=$HOME/bin/alpha:$PATH
  658.                SHELL=$HOME/bin/alpha/rc
  659.                ;;
  660.             *)
  661.                echo 1>&2 "WARNING: unknown architecture"
  662.                SHELL=/bin/sh
  663.                ;;
  664.             esac
  665.  
  666.             # determine if this is a login shell
  667.             case $SHELL in
  668.             */rc)
  669.               case $0 in
  670.               -*)
  671.                  FLAG=-l
  672.                  ;;
  673.               esac
  674.               ;;
  675.             esac
  676.  
  677.             export PATH
  678.             export SHELL
  679.  
  680.             exec $SHELL $FLAG ${1+"$@"}
  681.  
  682.             # end-of-file
  683.  
  684.         The dance to capture the output of uname is necessary because of
  685.         a bug whereby redirection does not work in the original v7 sh if
  686.         stdout is closed.  (This bug lives on in the Ultrix /bin/sh.)
  687.  
  688.         The easiest way to manage shell scripts is to keep a master copy
  689.         in a central directory, say $home/bin/share, and have slave
  690.         scripts in machine-specific directories which source the master
  691.         script.  For example, for a command called `foo' create the
  692.         following in each machine-specific directory:
  693.  
  694.             #! /full/path/to/machine/specific/rc
  695.             . $home/bin/share/foo $*
  696.             # end-of-file
  697.  
  698.         See 5.3 if your cluster contains Apollos.
  699.  
  700. 5.3     What problems occur with rc on Apollos?
  701.  
  702.         Apollos require the login shell to be a binary, so you cannot
  703.         use a sh script wrapper around rc.
  704.  
  705. 5.4     What problems occur with rc on SYSV-derived systems?
  706.  
  707.         Many SYSV-derived sh and ksh are `restricted' if the final
  708.         component of SHELL contains the letter `r'.  A restricted shell
  709.         will not allow you to cd, perform output redirection, set PATH,
  710.         or specify absolute paths to executables, meaning that many
  711.         shell scripts written in sh or ksh will fail.  This is also
  712.         applies to BSD-derived systems that also ship with a SYSV-
  713.         derived shell (for example, /bin/sh5 on Ultrix).
  714.  
  715.         One solution is to link rc to a file that does not contain the
  716.         letter `r', and use that file as your SHELL.  You can achieve
  717.         this automatically by placing the following commands in your
  718.         .rcrc:
  719.  
  720.             rcdir = `{ dirname $SHELL } {
  721.                 test -f $rcdir/RC || ln $rcdir/rc $rcdir/RC
  722.                 SHELL = $rcdir/RC
  723.             }
  724.  
  725.         Make sure when you install a new version of rc that you remove
  726.         the previous RC.
  727.  
  728.         This behaviour is also a potential problem if you use a sh
  729.         wrapper around rc as your login shell (see 5.2 and 6.3).  Make
  730.         sure that the name of the wrapper does not contain the letter
  731.         `r'.
  732.  
  733. 5.5     What problems occur with rc on NeXTs?
  734.  
  735.         The NeXT window system assumes that all shells are `job control'
  736.         shells and will place themselves in a new process group.
  737.         Contrary to this assumption, rc is not a job control shell and
  738.         so does not do this.  The result is that a signal to one (such
  739.         as an interrupt) will be sent to all.
  740.  
  741.         The `newpgrp' builtin-in command was provided to deal with this
  742.         problem.  You can use it to ensure that each new interactive rc
  743.         belongs to a new process group by using a prompt function to run
  744.         code in each new interactive instance of rc (see 6.1 and 6.2).
  745.         Other more elegant solutions (such as a wrapper around rc) are
  746.         precluded by the uncooperative and inflexible nature of the NeXT
  747.         window system.
  748.  
  749.         See also 6.1 and 6.2.
  750.  
  751. 5.6     How do I keep down the size of my .rcrc file?
  752.  
  753.         Given the nature of rc, the natural place to define functions is
  754.         in the .rcrc file.  However, as the number of functions grows,
  755.         it becomes more awkward to maintain them all in a single file.
  756.         One solution is to break out the functions into separate files
  757.         and automatically load them within .rcrc:
  758.  
  759.             fnlib = $home/fnlib
  760.             fn load { ~ $#* 1 && builtin . $fnlib/$1 }
  761.             builtin cd $fnlib
  762.             name = () for ( name in * ) load $name
  763.             builtin cd
  764.  
  765.         See also 5.7.
  766.  
  767. 5.7     How do I speed up the execution of my .rcrc file?
  768.  
  769.         If you have lots of functions, you may wish to use lazy function
  770.         loading:
  771.  
  772.             fnlib = $home/fnlib
  773.             fn load { ~ $#* 1 && builtin . $fnlib/$1 }
  774.             builtin cd $fnlib
  775.             name = () for ( name in * ) fn $name { load $0 && $0 $* }
  776.             builtin cd
  777.  
  778.         Often, though, a more substantial amount of time is spent
  779.         testing directories before they are added to a path: rc does not
  780.         have a built-in test command, so each test implies a fork and an
  781.         exec.  In some circumstances, you can replace the test with code
  782.         similar to the following:
  783.  
  784.             path = ()
  785.             dir = () for ( dir in ... )
  786.                 builtin cd $dir >[1=] >[2=] && path = ( $path $dir )
  787.             builtin cd
  788.  
  789.         See also 5.6 and 4.13.
  790.  
  791. 6.      Interactions between rc and the rest of UNIX
  792.  
  793. 6.1     How do I get each new interactive rc to do ...?
  794.  
  795.         Rather than set the `-l' flag and place the code in .rcrc, you
  796.         can use a prompt function like the following:
  797.  
  798.             fn prompt {
  799.                 if ( ! ~ $ipid $pid ) {
  800.                     ipid=$pid
  801.                     ...
  802.                 }
  803.             }
  804.  
  805.         This will run ... at the start of each new interactive instance
  806.         of rc, but not in non-interactive instances of rc.
  807.  
  808.         See also 6.2 and 5.5.
  809.  
  810. 6.2     How do I get rc to do ... in each new xterm?
  811.  
  812.         Since xterm puts WINDOWID into the environment, you can use a
  813.         prompt function like the following:
  814.  
  815.             fn prompt {
  816.                 if ( ! ~ $wid $WINDOWID && ~ $TERM xterm* ) {
  817.                     wid=$WINDOWID
  818.                     ...
  819.                 }
  820.             }
  821.  
  822.         See also 6.1.
  823.  
  824. 6.3     How do I get rc to read .rcrc when I use rsh?
  825.  
  826.         rshd does not place a `-' in the first character of argv[0] when
  827.         it execs a shell, so .rcrc is not run and this can cause
  828.         problems.
  829.  
  830.         One solution is to have a false login shell called login-shell
  831.         that explicitly supplies a -l flag to rc, i.e., login-shell
  832.         contains:
  833.  
  834.             #! /path/to/rc
  835.             exec /path/to/rc -l $*
  836.             # end-of-file
  837.  
  838.         See also 5.2.
  839.  
  840. 6.4     How do I get at or batch to run an rc script?
  841.  
  842.         at and batch only accept sh or csh scripts, so you need to
  843.         package your rc script in a sh wrapper.  The following two
  844.         functions accomplish this.  Note that they do not completely
  845.         emulate the standard commands, as they will not accept a file
  846.         name on the command line, but rather only read commands from
  847.         stdin.  A simple further enhancement might be to mail the stdout
  848.         and stderr of the job back to the user.
  849.  
  850.             fn at {
  851.                 if ( ~ $#* 0 ) {
  852.                     echo >[2=1] \
  853.                         'usage: at [ time [day] | -r job ... | -l [job ...] ]'
  854.                     return 1
  855.                 }
  856.                 switch ( $1 ) {
  857.                 case -r
  858.                     builtin at $*
  859.                 case -l
  860.                     builtin at $* >[2=1]
  861.                 case *
  862.                     {
  863.                         echo 'SHELL='^$SHELL
  864.                         echo 'export SHELL'
  865.                         echo 'sed ''s/^-//'' <<''+'' | '^$SHELL
  866.                         sed 's/^/-/'
  867.                         echo '+'
  868.                     } | SHELL = /bin/sh builtin at $*
  869.                 }
  870.             }
  871.  
  872.             fn batch {
  873.                 if ( ! ~ $#* 0 ) {
  874.                     echo >[1=2] 'usage: batch'
  875.                     return 1
  876.                 }
  877.                 {
  878.                     echo 'SHELL='^$SHELL
  879.                     echo 'export SHELL'
  880.                     echo 'sed ''s/^-//'' <<''+'' | '^$SHELL
  881.                     sed 's/^/-/'
  882.                     echo '+'
  883.                 } | SHELL = /bin/sh builtin batch
  884.             }
  885.  
  886. 7.      Programming in rc
  887.  
  888. 7.1     What makes rc such a good scripting language?
  889.  
  890.         Brian Kernighan and Rob Pike wrote of the original v7 Bourne
  891.         shell:
  892.  
  893.             The UNIX shell isn't typical of command interpreters:
  894.             although it lets you run commands in the usual way, because
  895.             it is a programming language it can accomplish much more.
  896.  
  897.         Their comments apply equally to rc, perhaps more so.
  898.  
  899.         The two aspects of rc that contribute most to its utility as a
  900.         scripting language are its simple quoting rule coupled with the
  901.         absence of rescanning and the fact that the language is small,
  902.         simple, and well defined.
  903.  
  904.         The former allows one to write scripts with complete control
  905.         over the lexical aspects of the process: when and if globbing,
  906.         pattern matching, and list formation take place.  Tom Duff wrote
  907.         that rc is `not a macro processor'.  The lack or rescanning,
  908.         together with improvements to backquote substitutions, allowed
  909.         him to collapse Bourne's four types of quoting down to one,
  910.         eliminating all of their complex interactions.
  911.  
  912.         The latter means that the whole language can be readily
  913.         understood by the user.  Its grammar is well defined, in sharp
  914.         contrast to sh.  (Indeed, a skeleton yacc grammar is included as
  915.         an appendix to rc's manual page.)  The language is small and
  916.         well defined; there are, to quote John Mackin, no `dark
  917.         corners'.  Although the language is smaller and simpler, it
  918.         retains all the power and flexibility of sh, and improves and
  919.         extends on it in several areas.
  920.  
  921. 7.2     What are the trade-offs between functions and scripts?
  922.  
  923.         Functions are run in the process that invokes them, so they can
  924.         make persistent changes to the environment of the interpreter.
  925.         They are essential for some actions (reading a variable, for
  926.         example).
  927.  
  928.         Functions make excellent wrappers around standard commands, as
  929.         one can use the `builtin' command to invoke the standard command
  930.         from within the function.  Invoking a standard command from
  931.         within a script of the same name involves either hard-wiring the
  932.         name into the script or using a more elaborate method, such as
  933.         the `pathos' script posted to the mailing list in June 1992.
  934.  
  935.         There is less overhead in invoking a function, as the kernel
  936.         need not exec rc once again.
  937.  
  938.         However, functions take up space in the environment.  There is
  939.         often a hard limit on the size of the environment.  Although on
  940.         some systems this limit is very large, on others it is not.  In
  941.         addition, very large environments can degrade the performance of
  942.         fork.
  943.  
  944.         Functions cannot be exec-ed directly by a C program, but must be
  945.         invoked through rc, although it is probably a good idea to do
  946.         this anyway, as responsibility for globbing and variable
  947.         substitution properly resides with the shell.
  948.  
  949. 7.3     What can I do if I have deficient sed, awk, test, ... ?
  950.  
  951.         Shell programming on UNIX rests on two foundations: the shell
  952.         itself and the toolkit of programs provided in /bin and
  953.         /usr/bin.  Unfortunately, many vendors provide out-of-date tools
  954.         and there are many incompatibilities between BSD- and SYSV-
  955.         derived systems, so writing portable scripts is a problem.  This
  956.         problem can be especially acute in heterogeneous clusters.
  957.  
  958.         There are two approaches to this problem: one is to use only
  959.         those tools and options that were present in v7, and the other
  960.         is to use only those tools and options that are present in
  961.         POSIX.2, and to replace the vendor-supplied tools with those
  962.         from GNU if the former do not conform (see 7.4).
  963.  
  964. 7.4     Where do I obtain the GNU tools and other software?
  965.  
  966.         Get prep.ai.mit.edu:/pub/gnu/GNUinfo/FTP by anonymous FTP for a
  967.         list of sites that archive GNU software.
  968.  
  969.         The article `How to find sources' lists sites that archive
  970.         software posted to Usenet source newgroups.  This article is
  971.         regularly cross-posted to comp.sources.wanted, comp.answers, and
  972.         news.answers, and is also available via anonymous FTP as
  973.         rtfm.mit.edu:/pub/usenet/comp.answers/finding-sources.
  974.  
  975. 7.5     How do I perform arithmetic in rc?
  976.  
  977.         You can use /bin/expr, /bin/awk, or unary arithmetic with lists
  978.         (see 7.6 for an example).
  979.  
  980. 7.6     How do I find the first occurrence of an element in a list?
  981.  
  982.         Use an `index' function, as in:
  983.  
  984.             ; x = ( a b a b )
  985.             ; index b $x
  986.             2
  987.  
  988.         This implementation of index uses a list to count up to the
  989.         index of the element:
  990.  
  991.             fn index {
  992.                 switch ( $#* ) {
  993.                 case 0 1
  994.                     echo >[1=2] 'usage: index pattern list ...'
  995.                     return 1
  996.                 case *
  997.                     elem = $1 prefix = () {
  998.                         shift
  999.                         if ( ! ~ $elem $* ) {
  1000.                             echo 0
  1001.                             return 1
  1002.                         }
  1003.                         while ( prefix = ( $prefix $1 ) && ! ~ $elem $1 )
  1004.                             shift
  1005.                         echo $#prefix
  1006.                         return 0
  1007.                     }
  1008.                 }
  1009.             }
  1010.  
  1011. 7.7     How do I use ranges in array subscripts in rc?
  1012.  
  1013.         Use a `seq' function, as in:
  1014.  
  1015.             ; x = ( a b c d e f g h )
  1016.             ; echo $x( `{seq 2 5} )
  1017.             b c d e
  1018.  
  1019.         There are many implementations of seq, most of which use awk,
  1020.         like this one:
  1021.  
  1022.             fn seq {
  1023.                 switch ( $#* ) {
  1024.                 case 1
  1025.                     * = ( 1 $1 )
  1026.                 case 2
  1027.                 case *
  1028.                     echo >[1=2] usage: seq [start] stop
  1029.                     return 1
  1030.                 }
  1031.                 echo $1 $2 | awk '{
  1032.                     if ( $1 <= $2 )
  1033.                         for ( i = $1; i <= $2; i++ ) print i;
  1034.                     else
  1035.                         for ( i = $1; i >= $2; i-- ) print i;
  1036.                 }'
  1037.             }
  1038.  
  1039. 7.8     How do I perform the equivalent of read in rc?
  1040.  
  1041.         Use a `read' function, to read a single line from stdin, remove
  1042.         the trailing newline, and assign it to a variable:
  1043.  
  1044.             ; read foo
  1045.             Do the funky gibbon!
  1046.             ; echo $foo
  1047.             Do the funky gibbon!
  1048.             ; echo $#foo
  1049.             1
  1050.  
  1051.         The following implementation of read returns 1 if EOF is seen,
  1052.         like the read in the v7 sh:
  1053.  
  1054.             fn read {
  1055.                 if ( ! ~ $#* 1 ) {
  1056.                     echo >[1=2] 'usage: read variable'
  1057.                     return 1
  1058.                 }
  1059.                 if ( ~ $1 '*' () *'='* ) {
  1060.                     echo >[1=2] 'read: bad variable name'
  1061.                     return 1
  1062.                 }
  1063.                 lines = () nl = () {
  1064.                     ifs = () { nl = `{ echo } }
  1065.                     ifs = $nl { lines = `{ line ; echo $status } }
  1066.                     if ( ~ $#lines 2 ) {
  1067.                         $1 = $lines(1)
  1068.                         return 0
  1069.                     } else {
  1070.                         $1 = ''
  1071.                         return $lines(1)
  1072.                     }
  1073.                 }
  1074.             }
  1075.  
  1076.         If your UNIX does not have a line command, the following is an
  1077.         straightforward substitute.
  1078.  
  1079.             #include <unistd.h>
  1080.             int main ()
  1081.             {
  1082.                 unsigned char c;
  1083.  
  1084.                 while (read (0, &c, 1) == 1 && c != '\n')
  1085.                     write (1, &c, 1);
  1086.                 write (1, "\n", 1);
  1087.                 return c != '\n';
  1088.             }
  1089.  
  1090.         Attempts to use standard UNIX utilities (e.g., "sed 1q", "head
  1091.         -1", and "awk '{ print; exit; }'") to replace the line command
  1092.         fail because line does not buffer its input.  This was discussed
  1093.         extensively in the mailing list in September 1991 (see 2.2).
  1094.  
  1095.         Alternatively, a patch to add a builtin read was posted to the
  1096.         mailing list in September 1993 (see 1.4).
  1097.  
  1098. Acknowledgements
  1099.  
  1100. Many people have contributed ideas, code, and information to this
  1101. document, either directly or indirectly, through the rc mailing list and
  1102. its influence on my understanding of rc.
  1103.  
  1104. People who have directly contributed to this document include Vincent
  1105. Broman, Raymond Chen, Tom Culliton, Stefan Dalibor, Jim Davis, Matt Day,
  1106. Matthew Farwell, David Fiander, Tim Goodwin, Paul Haahr, Charles Hannum,
  1107. David Hogan, Noel Hunt, John LoVerso, Hamish Macdonald, John Mackin,
  1108. Byron Rakitzis, Boyd Roberts, Rich Salz, Chris Siebenmann, Emin Gun
  1109. Sirer, Icarus Sparry, Gerry Tomlinson, Malte Uhl, Christopher Vance, and
  1110. Victor Zandy.  My apologies to anyone I have missed.
  1111.  
  1112. As a user of rc, I am indebted to Tom Duff for its design, to Steve
  1113. Bourne for its foundation, and to Byron Rakitzis for its implementation.
  1114.  
  1115. Alan Watson (alan@oldp.astro.wisc.edu)
  1116.